// Created by Windward Studios - no copyright is claimed. This code can be used in
// any manner by anyone for any reason. There is no copyright of any kind on it. You may
// use it in commercial products. You may change it without sharing those changes.
// We ask that you keep the "created by Windward Studios" in a comment at the top.

using System;

namespace net.windward.utils.ado
{
	/// <summary>
	/// The base class for tables, views, stored procedures, and columns. An element of a database.
	/// </summary>
	public abstract class WrDbElement : IComparable
	{
		private readonly string schema;
		protected readonly string name;
		protected readonly string description;

		/// <summary>
		/// Create an element object.
		/// </summary>
		/// <param name="schema">The schema that owns this element. null if none, empty string if default and the default has no name.</param>
		/// <param name="name">The name of the element.</param>
		/// <param name="description">The description (metadata) of the element.</param>
		protected WrDbElement(string schema, string name, string description)
		{
			this.schema = schema;
			this.name = name;
			this.description = description;
		}

		/// <summary>
		/// Copy constructor
		/// </summary>
		/// <param name="src">Source object.</param>
		protected WrDbElement(WrDbElement src)
		{
			schema = src.schema;
			name = src.name;
			description = src.description;
		}

		/// <summary>
		/// The schema that owns this element. null if none, empty string if default and the default has no name.
		/// </summary>
		public string Schema
		{
			get { return schema; }
		}

		/// <summary>
		/// The name of this element. If there is a schema it is not included.
		/// </summary>
		public string Name
		{
			get { return name; }
		}

		/// <summary>
		/// The full name of the element including the schema.
		/// </summary>
		public virtual string FullName
		{
			get
			{
				if (string.IsNullOrEmpty(schema))
					return name;
				return schema + '.' + name;
			}
		}

		/// <summary>
		/// The description (metadata) of the element.
		/// </summary>
		public virtual string Description
		{
			get { return description; }
		}

		#region Implementation of IComparable

		/// <summary>
		/// Compares the current instance with another object of the same type.
		/// </summary>
		/// <returns>
		/// A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This instance is less than <paramref name="obj"/>. Zero This instance is equal to <paramref name="obj"/>. Greater than zero This instance is greater than <paramref name="obj"/>. 
		/// </returns>
		/// <param name="obj">An object to compare with this instance. </param><exception cref="T:System.ArgumentException"><paramref name="obj"/> is not the same type as this instance. </exception><filterpriority>2</filterpriority>
		public int CompareTo(object obj)
		{
			WrDbElement elem = obj as WrDbElement;
			if (elem == null)
				throw new ArgumentException("must compare to WrDbElement");

			// if both do/don't have schema - use FullName (which is Name for no schema)
			if ((string.IsNullOrEmpty(schema) && string.IsNullOrEmpty(elem.schema)) ||
						((! string.IsNullOrEmpty(schema)) && (! string.IsNullOrEmpty(elem.schema))))
				return FullName.CompareTo(elem.FullName);

			// no schema first
			if (string.IsNullOrEmpty(schema))
				return -1;
			return 1;
		}

		#endregion
	}
}
